package day9;
// synchronized修饰符
public
class TestSynchronized {
    // 普通方法
    public synchronized void printA(){
        String name=Thread.currentThread().getName();
        System.out.println(name+"正在执行printA方法");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+"执行printA方法完毕");
    }
    // 静态方法
    public synchronized static void printB(){
        String name=Thread.currentThread().getName();
        System.out.println(name+"正在执行printB方法");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+"执行printB方法完毕");
    }
    //同步方法:同一个对象 同步方法都是同一个锁（锁当前this对象）
    public synchronized void printC(){
        String name=Thread.currentThread().getName();
        System.out.println(name+"正在执行printC方法");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+"执行printC方法完毕");
    }
    //静态同步方法   锁的是当前类的class对象   类名.class
    public static synchronized void printD(){
        String name=Thread.currentThread().getName();
        System.out.println(name+"正在执行printD方法");
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+"执行printD方法完毕");
    }

    public static void main(String[] args) {
        TestSynchronized ts=new TestSynchronized();
        TestSynchronized ts1=new TestSynchronized();
        //A和C调用的都是同步方法 锁的是当前的this对象
        //属于同一把锁 A和C只能有一个线程能执行 一个线程执行完了 另一个线程才能执行

        //B和D调用的都是静态同步方法 锁的是当前类的class对象
        //属于同一把锁 B和D只能有一个线程能执行 一个线程执行完了 另一个线程才能执行
        new Thread(()->{
            ts.printA();//锁的是ts对象 this-->ts
        },"AAA").start();
        new Thread(()->{
            ts.printC();//锁的是ts对象 this-->ts
        },"CCC").start();
        new Thread(()->{
            ts1.printD();//锁类对象 类名.class
        },"DDD").start();
        new Thread(()->{
            ts.printB();//类对象 类名.class
        },"BBB").start();
    }
}
class TestSynchronized1{
    public synchronized void printC(){
        String name=Thread.currentThread().getName();
        System.out.println(name+"正在执行printC方法");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+"执行printC方法完毕");
    }
}